const https = require('https');
const { URL } = require('url');

/**
 * 简单的 fetch 替代函数，使用内置 https 模块
 * @param {string} url 请求URL
 * @param {Object} options 请求选项
 * @returns {Promise<Object>} 响应对象
 */
function fetch(url, options = {}) {
  return new Promise((resolve, reject) => {
    const urlObj = new URL(url);

    const requestOptions = {
      hostname: urlObj.hostname,
      port: urlObj.port || 443,
      path: urlObj.pathname + urlObj.search,
      method: options.method || 'GET',
      headers: options.headers || {}
    };

    const req = https.request(requestOptions, (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        resolve({
          json: () => Promise.resolve(JSON.parse(data)),
          text: () => Promise.resolve(data),
          status: res.statusCode,
          ok: res.statusCode >= 200 && res.statusCode < 300
        });
      });
    });

    req.on('error', (error) => {
      reject(error);
    });

    if (options.body) {
      req.write(options.body);
    }

    req.end();
  });
}

/**
 * 微信小程序API工具类
 */
class WechatAPI {
  constructor() {
    this.appId = process.env.WECHAT_APP_ID;
    this.appSecret = process.env.WECHAT_APP_SECRET;

    if (!this.appId || !this.appSecret) {
      console.warn('⚠️ 微信小程序配置缺失，请检查环境变量 WECHAT_APP_ID 和 WECHAT_APP_SECRET');
    }
  }

  /**
   * 使用内置https模块发送请求（更可靠的实现）
   * @param {string} url 请求URL
   * @param {Object} options 请求选项
   * @returns {Promise<Object>} 响应对象
   */
  httpsRequest(url, options = {}) {
    return new Promise((resolve, reject) => {
      const urlObj = new URL(url);
      const postData = options.body || '';

      const requestOptions = {
        hostname: urlObj.hostname,
        port: urlObj.port || 443,
        path: urlObj.pathname + urlObj.search,
        method: options.method || 'GET',
        headers: {
          'Content-Length': Buffer.byteLength(postData),
          ...options.headers
        }
      };

      console.log('发送HTTPS请求:', { url, method: options.method, postData });

      const req = https.request(requestOptions, (res) => {
        let data = '';

        res.on('data', (chunk) => {
          data += chunk;
        });

        res.on('end', () => {
          console.log('HTTPS响应:', {
            status: res.statusCode,
            statusMessage: res.statusMessage,
            headers: res.headers,
            data: data
          });

          try {
            const jsonData = JSON.parse(data);
            resolve({
              text: () => Promise.resolve(data),
              json: () => Promise.resolve(jsonData),
              status: res.statusCode,
              statusText: res.statusMessage,
              ok: res.statusCode >= 200 && res.statusCode < 300,
              headers: new Map(Object.entries(res.headers)),
              data: jsonData // 直接提供解析后的数据
            });
          } catch (parseError) {
            // 如果不是JSON，也返回响应对象
            resolve({
              text: () => Promise.resolve(data),
              json: () => Promise.reject(parseError),
              status: res.statusCode,
              statusText: res.statusMessage,
              ok: res.statusCode >= 200 && res.statusCode < 300,
              headers: new Map(Object.entries(res.headers)),
              data: data
            });
          }
        });
      });

      req.on('error', (error) => {
        console.error('HTTPS请求错误:', error);
        reject(error);
      });

      if (postData) {
        req.write(postData);
      }
      req.end();
    });
  }

  /**
   * 通过code换取用户的openid和session_key
   * @param {string} code 小程序端通过wx.login()获取的code
   * @returns {Promise<Object>} 包含openid和session_key的对象
   */
  async code2Session(code) {
    if (!this.appId || !this.appSecret) {
      throw new Error('微信小程序配置缺失');
    }

    const url = 'https://api.weixin.qq.com/sns/jscode2session';
    const params = new URLSearchParams({
      appid: this.appId,
      secret: this.appSecret,
      js_code: code,
      grant_type: 'authorization_code'
    });

    try {
      const response = await fetch(`${url}?${params}`);
      const data = await response.json();

      if (data.errcode) {
        console.error('微信code2Session错误:', data);
        throw new Error(`微信登录失败: ${data.errmsg || '未知错误'}`);
      }

      return {
        openid: data.openid,
        session_key: data.session_key,
        unionid: data.unionid // 可能为空
      };
    } catch (error) {
      console.error('调用微信code2Session接口失败:', error);
      throw new Error('微信登录服务异常');
    }
  }

  /**
   * 获取小程序全局唯一后台接口调用凭据（access_token）
   * @returns {Promise<string>} access_token
   */
  async getAccessToken() {
    if (!this.appId || !this.appSecret) {
      throw new Error('微信小程序配置缺失');
    }

    const url = 'https://api.weixin.qq.com/cgi-bin/token';
    const params = new URLSearchParams({
      grant_type: 'client_credential',
      appid: this.appId,
      secret: this.appSecret
    });

    try {
      const response = await fetch(`${url}?${params}`);
      const data = await response.json();

      if (data.errcode) {
        console.error('获取access_token错误:', data);
        throw new Error(`获取access_token失败: ${data.errmsg || '未知错误'}`);
      }

      return data.access_token;
    } catch (error) {
      console.error('获取access_token失败:', error);
      throw new Error('获取access_token服务异常');
    }
  }

  /**
   * 检查文本内容是否违规
   * @param {string} content 要检查的文本内容
   * @returns {Promise<Object>} 检查结果
   */
  async msgSecCheck(content) {
    try {
      const accessToken = await this.getAccessToken();
      const url = `https://api.weixin.qq.com/wxa/msg_sec_check?access_token=${accessToken}`;
      
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          content: content,
          version: 2,
          scene: 1,
          openid: 'test_openid' // 可以是实际的openid
        })
      });

      const data = await response.json();
      
      if (data.errcode === 0) {
        return {
          isValid: true,
          result: data.result
        };
      } else {
        console.error('内容安全检查错误:', data);
        return {
          isValid: false,
          errcode: data.errcode,
          errmsg: data.errmsg
        };
      }
    } catch (error) {
      console.error('内容安全检查失败:', error);
      // 检查失败时默认通过，避免影响正常业务
      return {
        isValid: true,
        error: error.message
      };
    }
  }

  /**
   * 获取用户手机号
   * @param {string} code 手机号授权code
   * @param {string} openid 用户openid（可选，但建议提供）
   * @returns {Promise<Object>} 包含手机号信息的对象
   */
  async getPhoneNumber(code, openid = null) {
    try {
      const accessToken = await this.getAccessToken();
      console.log('获取access_token成功:',accessToken); 
      const url = `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${accessToken}`;

      // 构建请求体
      console.log('code:', code);
      const requestBody = { code };
      console.log('调用获取手机号接口:', { url, requestBody, accessToken: accessToken.substring(0, 10) + '...' });
      // 使用内置https模块发送请求（更可靠）
      const response = await this.httpsRequest(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      });


      // 直接使用响应中的data（已经在httpsRequest中解析过的JSON）
      const data = response.data;
      console.log('微信API响应数据:', JSON.stringify(data, null, 2));

      if (!data) {
        throw new Error(`微信API返回空数据 (HTTP ${response.status})`);
      }

      // 检查HTTP状态码
      if (!response.ok) {
        const errorMsg = data.errmsg || `HTTP ${response.status}`;
        const errorCode = data.errcode || response.status;
        throw new Error(`微信API请求失败: ${errorMsg} (errcode: ${errorCode})`);
      }

      if (data.errcode === 0) {
        return {
          phoneNumber: data.phone_info.phoneNumber,
          purePhoneNumber: data.phone_info.purePhoneNumber,
          countryCode: data.phone_info.countryCode
        };
      } else {
        console.error('获取手机号错误:', data);

        // 提供更详细的错误信息
        let errorMessage = `获取手机号失败: ${data.errmsg || '未知错误'} (errcode: ${data.errcode})`;

        // 针对常见错误码提供解决建议
        switch (data.errcode) {
          case 40001:
            errorMessage += ' - AppSecret错误或者AppSecret不属于这个小程序，请检查AppSecret的正确性';
            break;
          case 40013:
            errorMessage += ' - 不合法的AppID，请检查AppID是否正确';
            break;
          case 47001:
            errorMessage += ' - 解析数据失败，请检查数据格式';
            break;
          case 40029:
            errorMessage += ' - code无效，请重新获取';
            break;
          case 45011:
            errorMessage += ' - API调用太频繁，请稍候再试';
            break;
          case 48001:
            errorMessage += ' - API功能未授权，请确认小程序已获得该接口权限';
            break;
        }

        throw new Error(errorMessage);
      }
    } catch (error) {
      console.error('获取手机号失败:', error);
      throw new Error(`获取手机号服务异常: ${error.message}`);
    }
  }

  /**
   * 生成小程序码（用于分享）
   * @param {string} scene 场景值
   * @param {string} page 页面路径
   * @returns {Promise<Buffer>} 小程序码图片数据
   */
  async getWXACodeUnlimit(scene, page = 'pages/index/index') {
    try {
      const accessToken = await this.getAccessToken();
      const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${accessToken}`;

      const response = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          scene: scene,
          page: page,
          width: 430,
          auto_color: false,
          line_color: { r: 0, g: 0, b: 0 },
          is_hyaline: false
        })
      });

      if (response.headers.get('content-type').includes('image')) {
        return await response.buffer();
      } else {
        const data = await response.json();
        console.error('生成小程序码错误:', data);
        throw new Error(`生成小程序码失败: ${data.errmsg || '未知错误'}`);
      }
    } catch (error) {
      console.error('生成小程序码失败:', error);
      throw new Error('生成小程序码服务异常');
    }
  }
}

// 创建单例实例
const wechatAPI = new WechatAPI();

module.exports = wechatAPI;
